package com.dragon.logical.service.netty.impl;

import cn.hutool.core.util.StrUtil;
import com.dragon.common.netty.NettyPool;
import com.dragon.common.netty.NettyTools;
import com.dragon.logical.service.netty.NettyClientService;
import com.dragon.protoJo.bean.msg.ProtoMsg;
import io.netty.channel.Channel;
import io.netty.channel.pool.FixedChannelPool;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.FutureListener;
import org.springframework.stereotype.Service;

@Service
public class NettyClientServiceImpl implements NettyClientService {

    private static final String SERVER_ADDR = "127.0.0.1:18867";

    private static final String KEY = "msg-sn";


    /**
     * 使用netty连接池发送消息并返回响应结果
     *
     * @param serverAddr 消息发送地址
     * @param msg        消息发送内容
     * @return String 服务端响应内容
     */
    @Override
    public Boolean sendMsg(String serverAddr, ProtoMsg.Message msg) {
        final FixedChannelPool pool = getPool(SERVER_ADDR);
        //申请连接，没有申请到或者网络断开，返回null
        Future<Channel> future = pool.acquire();
        NettyTools.initReceiveMsg(KEY);
        // 组装发送数据
        future.addListener(new FutureListener<Channel>() {
            @Override
            public void operationComplete(Future<Channel> future) throws Exception {
                //给服务端发送数据
                Channel channel = future.getNow();
                //将消息发送到服务端
                channel.writeAndFlush(msg);
                // 连接放回连接池，这里一定记得放回去
                pool.release(channel);
            }
        });
        //等待并获取服务端响应
        String result = NettyTools.waitReceiveMsg(KEY);
        //该用户不在线，则直接推送该消息
        if(StrUtil.isNotBlank(result) && result.equals("1")){
            return false;
        }
        return true;
    }

    /**
     * @param serverAddr tcp服务端地址 host:port
     * @return FixedChannelPool
     */
    private FixedChannelPool getPool(String serverAddr) {
        if (NettyPool.poolMap == null || !NettyPool.poolMap.contains(serverAddr)) {
            //为null时初始化一次再获取
            new NettyPool();
        }
        return NettyPool.poolMap.get(serverAddr);
    }
}
